package com.starblink.android.basic.sensorsdata.exposure

import android.app.Activity
import android.graphics.Rect
import android.view.View
import android.view.ViewGroup
import android.view.Window
import com.starblink.android.basic.sensorsdata.exposure.config.ExposeConfig
import com.starblink.android.basic.tablayout.screenHeight
import com.starblink.android.basic.tablayout.screenWidth
import com.starblink.basic.autosize.utils.AutoSizeUtils
import com.starblink.basic.util.CommUtils

private const val TAG = "ExposeChecker"

class ExposeChecker {
    private var startTime: Long = 0

    fun updateStartTime() {
        startTime = System.currentTimeMillis()
    }

    fun isViewExpose(
        view: View,
        showRatio: Float = ExposeConfig.showRatio,
        exposeTime: Float = ExposeConfig.exposeTime
    ): Boolean {
        // 一般情况下 View调用此方法时直接上报 与ios一致
        return if (showRatio <= 0.01F && exposeTime <= 10F) {
            view.isInScreen(0.01F)
        } else {
            view.isInScreen(showRatio) && (System.currentTimeMillis() - startTime) >= exposeTime
        }
    }
}


fun View.isCover(showRatio: Float = ExposeConfig.showRatio): Boolean {
    var view = this
    val currentViewRect = Rect()
    val partVisible: Boolean = view.getLocalVisibleRect(currentViewRect) && view.isShown
    if (!partVisible) {
        return true
    }
    val totalHeightVisible =
        currentViewRect.bottom - currentViewRect.top >= view.measuredHeight * showRatio
    val totalWidthVisible =
        currentViewRect.right - currentViewRect.left >= view.measuredWidth * showRatio
    val totalViewVisible = partVisible && totalHeightVisible && totalWidthVisible
    if (!totalViewVisible)
        return true
    while (view.parent is ViewGroup) {
        val currentParent = view.parent as ViewGroup
        if (currentParent.visibility != View.VISIBLE) //if the parent of view is not visible,return true
            return true

        val start = view.indexOfViewInParent(currentParent)
        for (i in start + 1 until currentParent.childCount) {
            val viewRect = Rect()
            view.getGlobalVisibleRect(viewRect)
            val otherView = currentParent.getChildAt(i)
            val otherViewRect = Rect()
            otherView.getGlobalVisibleRect(otherViewRect)
            if (Rect.intersects(viewRect, otherViewRect)) {
                //if view intersects its older brother(covered),return true
                return true
            }
        }
        view = currentParent
    }
    return false
}

fun View.indexOfViewInParent(parent: ViewGroup): Int {
    var index = 0
    while (index < parent.childCount) {
        if (parent.getChildAt(index) === this) break
        index++
    }
    return index
}

private fun View.rootViewRect(): Rect {
    return if (this.context is Activity) {
        val rect = Rect()
        val activtiy = (context as Activity)
        if (rootView == activtiy.window.decorView) {
            activtiy.window.decorView.findViewById<View>(Window.ID_ANDROID_CONTENT)
                .getGlobalVisibleRect(rect)
        } else {
            (rootView ?: activtiy.window.decorView.findViewById<View>(Window.ID_ANDROID_CONTENT))
                .getGlobalVisibleRect(rect)
        }
        rect
    } else {
        Rect(0, 0, screenWidth, screenHeight)
    }
}

fun View.isInScreen(showRatio: Float = ExposeConfig.showRatio): Boolean {
    val view = this

    val currentViewRect = Rect()
    val globalVisible: Boolean = view.getGlobalVisibleRect(currentViewRect)
    if (view.isShown.not() || globalVisible.not() || view.windowToken == null) {
        return false
    }

    val rootViewRect = view.rootViewRect()

    val totalHeightVisible =
        currentViewRect.top + (view.measuredHeight * showRatio).toInt() <= rootViewRect.height()
    val totalWidthVisible =
        currentViewRect.left + (view.measuredWidth * showRatio).toInt() <= rootViewRect.width()

    //Log.d("isInScreen", "-->> ${view.javaClass.simpleName} , rootViewRect: $rootViewRect, currentViewRect:${currentViewRect}, height: ${view.measuredHeight}, ${view.getTrackData()}")

    return totalHeightVisible && totalWidthVisible
}


fun View.isInScreenGuide(showRatio: Float = 1F): Boolean {
    val view = this

    val currentViewRect = Rect()
    CommUtils.getScreenWidth()
    val globalVisible: Boolean = view.getGlobalVisibleRect(currentViewRect)
    if (view.isShown.not() || globalVisible.not() || view.windowToken == null) {
        return false
    }

    val rootViewRect = view.rootViewRect()

    val totalHeightVisible =
        currentViewRect.top + (view.measuredHeight * showRatio).toInt() <= rootViewRect.height()
    val totalWidthVisible =
        currentViewRect.left + (view.measuredWidth * showRatio).toInt() <= rootViewRect.width()

    //Log.d("isInScreen", "-->> ${view.javaClass.simpleName} , rootViewRect: $rootViewRect, currentViewRect:${currentViewRect}, height: ${view.measuredHeight}, ${view.getTrackData()}")

    return totalHeightVisible && totalWidthVisible
}

fun View.isInScreenCenter(showRatio: Float = ExposeConfig.showRatio): Boolean {
    val view = this

    val currentViewRect = Rect()
    val globalVisible: Boolean = view.getGlobalVisibleRect(currentViewRect)
    if (view.isShown.not() || globalVisible.not() || view.windowToken == null) {
        return false
    }

    val rootViewRect = view.rootViewRect()

    val totalHeightVisible =
        currentViewRect.top + view.measuredHeight * showRatio <= rootViewRect.height()
    val totalWidthVisible =
        currentViewRect.left + view.measuredWidth * showRatio <= rootViewRect.width()

    val playTop = com.starblink.basic.ext.screenHeight / 2 - AutoSizeUtils.dp2px(200f)
    val playBottom = com.starblink.basic.ext.screenHeight / 2 + AutoSizeUtils.dp2px(200f)

    val screenPosition = IntArray(2)
    view.getLocationOnScreen(screenPosition)
    val halfHeight: Int = view.height / 2
    val rangePosition = screenPosition[1] + halfHeight
    //中心点在播放区域内
    var isCenter = false
    if (rangePosition in playTop..playBottom) {
        isCenter = true
    }

//    YYLogUtils.e(
//        " guide ${totalHeightVisible && totalWidthVisible && isCenter}  -->> ${view.javaClass.simpleName} , rootViewRect: $rootViewRect, currentViewRect:${currentViewRect}, height: ${view.measuredHeight} }"
//    )

    return totalHeightVisible && totalWidthVisible && isCenter
}